﻿module DiffableExample

open System.IO
open Diffable

let viewDOTGraph (string : string) = 
    let outStream = new StreamWriter("temp.dot")
    outStream.Write string
    outStream.Close()
    
    //Create a new process to build an svg based on the graphviz
    //file we have just written.
    let graphvizProc = System.Diagnostics.Process.Start(
        "dot",
        "-Tsvg -o \"temp.svg\" -Kdot \"temp.dot\""
    ) 

    graphvizProc.WaitForExit()

    //Display the svg in a viewer.
    let squiggleProc = System.Diagnostics.Process.Start(
        "batik-squiggle.jar",
        "temp.svg"
    )    

    ()

type BST =
    | Internal of BST*BST*int
    | ValLeaf of int
    | NilLeaf

let EmptyBST = NilLeaf

let rec size bst =
    match bst with
        | Internal(leftChild,rightChild,value) ->
            (size leftChild) + (size rightChild) + 1
        | ValLeaf(value) ->
            1
        | NilLeaf ->
            0        

let diffInfo (bst : BST) (depth : int) =
    match bst with
        | Internal(leftChild, rightChild, value) ->
            {
                nodeLabel = value.ToString() + " (" + depth.ToString() + ")"
                children = [(leftChild, depth+1, "<="); (rightChild, depth+1, ">")]
                compFields = [value]
            }
        | ValLeaf(value) ->
            {
                nodeLabel = value.ToString() + " (" + depth.ToString() + ")"
                children = []
                compFields = [value]
            }
        | NilLeaf ->
            {
                nodeLabel = "*"
                children = []
                compFields = []
            }

let diffHelpers = Diffable.diffBundle diffInfo 0

let rec insert (bst : BST) (n : int) =
    match bst with
        | Internal(leftChild,rightChild,value) ->
            if n <= value then
                Internal(insert leftChild n, rightChild, value)
            else
                Internal(leftChild, insert rightChild n, value)
        | ValLeaf(value) ->
            if n <= value then
                Internal(ValLeaf(n), NilLeaf, value)
            else
                Internal(NilLeaf, ValLeaf(n), value)
        | NilLeaf ->
            ValLeaf(n)


let values = [3;4;-4;2]

let tree = List.fold insert EmptyBST values
viewDOTGraph (diffHelpers.treeDOTCode tree)

let treeList = List.scan insert EmptyBST values
viewDOTGraph (diffHelpers.treeListDOTCode treeList)
